<?php

/*
 * Author:  Viet.Dinh
 * Email:   viet.dinh@sutrixmedia.com
 * Version: 1.0
 * Package: Joomla component
 */

class phpImageMagick {

    protected $imageMagickPath = '';
    protected $imageQuality = 80;
    protected $originalFile = '';
    protected $sourceFile = '';
    protected $destinationFile = '';
    protected $classpath = '/usr/local/bin/';
    protected $dpi = 600;

    //protected $classpath = '/usr/bin/';

    function construct() {

        $this->setImageQuality(100);
    }

    function checkInstalled() {
        $script = system('rpm - qa | grep ImageMagick');
        if (!$script)
            return false;
        return true;
    }

    function setImageMagicPath($path) {
        $this->imageMagickPath = $path;
    }

    function setImageQuality($quality) {
        $this->imageQuality = $quality;
    }

    function setImageSource($source) {
        $this->sourceFile = $source;
    }

    function setImageDestination($des) {
        $this->destinationFile = $des;
    }

    function addText($text, $fontname, $fontsize, $color, $x, $y) {
        $fontsize = intval($fontsize * 4 / 3);
        $image_magick = $this->classpath . "convert";

        $command = $image_magick . ' "' . $this->sourceFile . '" ' .
                ' -font "' . $fontname . '"   -pointsize ' . $fontsize . ' -fill "' . $color . '" ' .
                ' -draw "text ' . $x . ', ' . $y . ' \'' . $text . '\'"  "' . $this->destinationFile . '"';

        passthru($command, $value);
        return $value;
    }

    function addImage($image, $x, $y, $hasmask = false) {
        $image_magick = $this->classpath . "composite ";

        //composite  -geometry +100+150
        if ($hasmask) {
            $sizes = getimagesize($this->sourceFile);
            //create a new png file
            $newbg = JPATH_ROOT . DS . 'tmp' . DS . time() . '.png';



            $command1 = $this->classpath . 'convert -size ' . $sizes[0] . 'x' . $sizes[1] . ' xc:transparent   -density ' . $this->dpi . ' -units PixelsPerInch ' . $newbg;
            passthru($command1, $value);


            $command = $image_magick . ' -geometry +' . $x . '+' . $y . ' ' . $image . ' ' . $newbg . ' ' . $newbg;
            passthru($command, $value);



            $command = $image_magick . ' -geometry +0+0 ' . $this->sourceFile . ' ' . $newbg . ' ' . $this->sourceFile;
            passthru($command, $value);

            @unlink($newbg);
        } else {
            $command = $image_magick . ' -geometry +' . $x . '+' . $y . ' ' . $image . ' ' . $this->sourceFile . ' ' . $this->sourceFile;
            passthru($command, $value);
        }


        @unlink($image);
        return $this->sourceFile;
    }

    function cropImage($source, $des, $width, $height, $x, $y) {
        $image_magick = $this->classpath;
        //$command = '/usr/bin/convert  -crop 100x150+100+15  '.$source_image.' new1.jpg';
        $command = $image_magick . 'convert  -crop ' . $width . 'x' . $height . '+' . $x . '+' . $y . ' ' . $source . ' ' . $des;
        passthru($command, $value);
        return $des;
    }

    function rotateImage($degree = 0, $source, $des) {
        $command = $this->classpath . 'convert  -rotate -' . $degree . '  ' . $source . ' ' . $des;
        passthru($command, $value);
        return $des;
    }

    function rotateGrey($degree = 0, $source, $des) {
        $command = $this->classpath . 'convert  -colorspace Gray  -rotate -' . $degree . '  ' . $source . ' ' . $des;
        passthru($command, $value);
        return $des;
    }

    function resizeImage($source, $percent, $des) {

        $command = $this->classpath . 'convert ' . $source . ' -resize ' . $percent . '%  ' . $des;
        passthru($command, $value);
        return $des;
    }

    function resizeImageWH($source, $width, $height, $des) {

        $command = $this->classpath . 'convert ' . $source . ' -resize ' . $width . 'x' . $height . '  ' . $des;
        passthru($command, $value);
        return $des;
    }

    function setDPI($source, $des) {
        $command = $this->classpath . 'convert ' . $source . ' -units "PixelsPerInch" -density ' . $this->dpi . '  ' . $des;
        passthru($command, $value);
        return $des;
    }

    function generate($srcImage, $arrElements, $rate) {
        $this->setImageSource($srcImage);
        $this->setImageDestination($srcImage);


        if ($arrElements) {
            $p1 = array();
            $p2 = array();
            foreach ($arrElements as $tempel) {
                switch ($tempel->type) {
                    case "background":
                        $hasmask = $tempel->hasmask;
                        break;
                    case "text":
                        $p1[] = $tempel;
                        break;
                    case "image":
                        $p2[] = $tempel;
                        break;
                }
            }
        }
        $arrElements = @array_merge($p2, $p1);
        $ind = 0;
        $org_fs = 0;
        $org_width = 0;


        foreach ($arrElements as $itemElement) {
            if ($itemElement->type == 'text') {
                $org_fs = $itemElement->fontsize;
                $org_width = $itemElement->width;
                if ($rate > 1) {
                    $itemElement->top = ceil($itemElement->top * $rate);
                    $itemElement->left = ceil($itemElement->left * $rate);
                    $itemElement->fontsize = number_format($itemElement->fontsize * $rate, 0) - 2;
                    $itemElement->width = ceil($itemElement->width * $rate);
                    $itemElement->height = ceil($itemElement->height * $rate);
                }
                $font = JPATH_ROOT . DS . 'fonts' . DS . $itemElement->fontname; // DO NOT FORGET TO CHANGE
                // getting bounding box 
                $text = $itemElement->value;
                $color = $itemElement->color;
                $bgcolor = $itemElement->bgcolor;


                $font_size = $itemElement->fontsize;

                $vwidth = $itemElement->width + 2;
                $fontbold = $itemElement->fontbold;

                $vpos = strpos($itemElement->fontname, $itemElement->fonttail);
                if ($vpos === false) {
                    if ($fontbold && $fontbold != "undefined") {
                        $temp = JPATH_ROOT . DS . 'fonts' . DS . $itemElement->fontname . '_bold.' . $itemElement->fonttail;
                        if (file_exists($temp))
                            $font = JPATH_ROOT . DS . 'fonts' . DS . $itemElement->fontname . '_bold.' . $itemElement->fonttail;
                    }
                    else
                        $font = JPATH_ROOT . DS . 'fonts' . DS . $itemElement->fontname . '.' . $itemElement->fonttail;
                }
                else
                    $font = JPATH_ROOT . DS . 'fonts' . DS . $itemElement->fontname;

                if ($font[strlen($font) - 1] == '.')
                    $font = substr($font, 0, strlen($font) - 1);

                $bbox = imagettfbbox($itemElement->fontsize, 0, $font, $itemElement->value);
                $textheight = $bbox[7] - $bbox[1];
                $text_width = $bbox[2] - $bbox[0]; // lower right corner - lower left corner
                $text_height = $bbox[7] - $bbox[1];

                // imagettfbbox returns very strange results 
                // so transforming them to plain width and height 

                $size_w = abs($bbox[2] - $bbox[0]);
                // width: right corner X - left corner X

                $size_h = abs($bbox[7] - $bbox[1]);
                $x = $itemElement->left;
                $y = $itemElement->top;

                $original = $arrElements[$ind];
                $stext = str_replace('~~~', chr(10), $itemElement->value);
                $stext = $this->wrap($org_fs, 0, $font, $stext, $org_width + 2);
                $arrtext = explode(chr(10), $stext);


                $distance_rate = $itemElement->lineheight ? $itemElement->lineheight : 0.3;
                $number = count($arrtext);


                if ($number > 1) {
                    $size_h = $number * $font_size + ($number - 1) * $font_size * $distance_rate;
                } else {
                    $size_h = $itemElement->height;
                }

                $size_w = $itemElement->width;




                if ($arrtext) {

                    $ins = 0;
                    $y = intval(($itemElement->height - ($number * $font_size + ($number - 1) * $font_size * $distance_rate)) / 2) + $font_size + $itemElement->top;

                    //	echo $itemElement->top." top<br>";
                    //	echo $y."y <br>";
                    foreach ($arrtext as $text) {

                        $bbox1 = imagettfbbox($itemElement->fontsize, 0, $font, $text);
                        $textheight = $bbox1[7] - $bbox1[1];
                        $tw1 = $bbox1[2] - $bbox1[0];
                        $x = $itemElement->left;


                        switch ($itemElement->textalign) {
                            case "left":
                                $x = $itemElement->left;
                                break;
                            case "right":
                                $vx = $itemElement->width - $tw1;
                                if ($vx < 0)
                                    $vx = $vx * (-1);
                                $x = $itemElement->left + $vx;
                                break;
                            case "center":
                                $vx = $itemElement->width - $tw1;
                                if ($vx < 0)
                                    $vx = $vx * (-1);
                                $x = $itemElement->left + ($vx) / 2;
                                break;
                            default:
                                $x = $itemElement->left;
                                break;
                        }



                        $y += $ins;

                        $this->addText($text, $font, $itemElement->fontsize, '#' . $itemElement->color, intval($x), intval($y));
                        $ins = intval($font_size * $distance_rate) + $font_size;
                    }//end foreach
                }//end if
            }
            else { //image
                if (!$itemElement->encImgPath) {
                    break;
                }

                $srcImageExecute = JPATH_ROOT . DS . urldecode($itemElement->encImgPath);

                $action = $itemElement->action;
                $rad = $itemElement->rad;

                $arrPath = split('/', $srcImageExecute);
                $arrName = split('\.', $arrPath[count($arrPath) - 1]);
                $fileName = $arrName[0] . date('-Y-m-d') . '.' . $arrName[1];
                $thumbImage = JPATH_ROOT . DS . 'tmp' . DS . $fileName;

                //increase DPI

                $thumbImage = $this->setDPI($srcImageExecute, $thumbImage);


                switch ($itemElement->action) {
                    case "rotate|gray":
                    case "gray|rotate":
                        $thumbImage = $this->rotateGrey($rad, $thumbImage, $thumbImage);
                        break;

                    case "rotate":
                        $thumbImage = $this->rotateImage($rad, $thumbImage, $thumbImage);
                        break;
                }
                /*
                  else {
                  $thumbImage= $this->rotateImage( $rad,$srcImageExecute, $thumbImage);
                  }
                 */


                $dims = getimagesize($thumbImage);
                $wThumbImage = $dims[0];
                $hThumbImage = $dims[1];
                $wrate = $wThumbImage / $itemElement->width;


                if ($itemElement->zoomWidth > $itemElement->width) {
                    $this->resizeImage($thumbImage, ($itemElement->zoomWidth / $itemElement->width) * 100, $thumbImage);
                }

                $s1_width = ceil($itemElement->width * $wrate);
                $s1_height = ceil($itemElement->height * $wrate);

                $x = $itemElement->insideLeft < 0 ? $itemElement->insideLeft * (-1) : $itemElement->insideLeft;
                $y = $itemElement->insideTop < 0 ? $itemElement->insideTop * (-1) : $itemElement->insideTop;
                $x = ceil($x * $wrate);
                $y = ceil($y * $wrate);


                $this->cropImage($thumbImage, $thumbImage, $s1_width, $s1_height, $x, $y);


                $this->resizeImageWH($thumbImage, ceil($itemElement->width * $rate), ceil($itemElement->height * $rate), $thumbImage);
                $this->addImage($thumbImage, ceil($itemElement->left * $rate), ceil($itemElement->top * $rate), $itemElement->hasmask);

                @unlink($thumbImage);
                //}//end else
            }//end if
            $ind++;
        }//end foreach
        //create cropmark

        return $newfile;
    }

//end function

    function finishSlide($newfile, $type = '', $rate = '', $width = false, $height = false) {
        if ($type == "label")
            $padding = 50;
        else
            $padding = 88;

        $ext_distance = ceil(0.583 / 2 * 600);
        list($newwidth, $newheight) = getimagesize($newfile);
        $this->resizeImageWH($newfile, $width ? $width : ($newwidth + $ext_distance), $height ? $height : ($newheight + $ext_distance), $newfile);
        $this->crossmarkImage($newfile, $padding, 3);
        return $newsite;
    }

    function execute($exe_str, $value) {
        passthru($exe_str, $value);
        return $value;
    }

    function wrap($fontSize, $angle, $fontFace, $string, $width = 100) {


        $ret = "";
        $arr = explode(' ', $string);
        foreach ($arr as $word) {

            $teststring = $ret . ' ' . $word;
            $testbox = imagettfbbox($fontSize, $angle, $fontFace, $teststring);
            if ($testbox[2] > $width) {
                $ret.=($ret == "" ? "" : chr(10)) . $word;
            } else {
                $ret.=($ret == "" ? "" : ' ') . $word;
            }
        }

        return $ret;
    }

    function islocal() {
        $host = trim(getenv("HTTP_HOST"));
        $found = strpos($host, '127.0.0.1');
        if ($found === 0)
            return TRUE;
        else
            return FALSE;
    }

    function itsImage($image) {
        if ($data = @getImageSize($image)) {
            return empty($this->allowed[$data[2]]) ? false : $data;
        } else {
            return false;
        }
    }

    function getCopyPosition($image, $nx, $ny, $position) {
        $data = getimagesize($image);
        $ox = $data[0];
        $oy = $data[1];

        switch ($position) {
            case 0:
                return array(0, 0);
            case 1:
                return array(ceil(($ox - $nx) / 2), 0);
            case 2:
                return array(($ox - $nx), 0);
            case 3:
                return array(0, ceil(($oy - $ny) / 2));
            case 4:
                return array(ceil(($ox - $nx) / 2), ceil(($oy - $ny) / 2));
            case 5:
                return array(($ox - $nx), ceil(($oy - $ny) / 2));
            case 6:
                return array(0, ($oy - $ny));
            case 7:
                return array(ceil(($ox - $nx) / 2), ($oy - $ny));
            case 8:
                return array(($ox - $nx), ($oy - $ny));
        }

        return array();
    }

    function crossmarkImage($source, $padding, $wmark = 11) {
        $image_magick = "/usr/bin/";
        $command = $image_magick . 'convert  -border ' . $padding . 'x' . $padding . ' -bordercolor white ' . $source . ' ' . $source;
        passthru($command, $value);

        //draw cross mark in 8 position
        $data = getimagesize($source);
        $x = $data[0];
        $y = $data[1];


        $distance = 60;
        //line 1
        $x11 = 0;
        $y11 = $padding + $distance;
        $x12 = $padding;
        $y12 = $padding + $distance;

        $cmd = ' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x11 . ',' . $y11 . ' ' . $x12 . ',' . $y12 . '" \ ';
        //passthru("convert $source $cmd $source", $value);
        //line 2
        $x21 = $padding + $distance;
        $y21 = 0;
        $x22 = $padding + $distance;
        $y22 = $padding;

        $cmd .=' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x21 . ',' . $y21 . ' ' . $x22 . ',' . $y22 . '" \ ';
        //passthru("convert $source $cmd $source", $value);
        //line3
        $x31 = $x - $padding - $distance;
        $y31 = 0;
        $x32 = $x - $padding - $distance;
        $y32 = $padding;

        $cmd .=' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x31 . ',' . $y31 . ' ' . $x32 . ',' . $y32 . '" \ ';
        //passthru("convert $source $cmd $source", $value);
        // line4
        $x41 = $x - $padding;
        $y41 = $padding + $distance;
        $x42 = $x;
        $y42 = $padding + $distance;

        $cmd .=' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x41 . ',' . $y41 . ' ' . $x42 . ',' . $y42 . '" \ ';
        //passthru("convert $source $cmd $source", $value);
        // line5
        $x51 = $x - $padding;
        $y51 = $y - $padding - $distance;
        $x52 = $x;
        $y52 = $y - $padding - $distance;

        $cmd .=' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x51 . ',' . $y51 . ' ' . $x52 . ',' . $y52 . '" \ ';
        //passthru("convert $source $cmd $source", $value);
        // line6
        $x61 = $x - $padding - $distance;
        $y61 = $y - $padding;
        $x62 = $x - $padding - $distance;
        $y62 = $y;

        $cmd .=' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x61 . ',' . $y61 . ' ' . $x62 . ',' . $y62 . '" \ ';
        //passthru("convert $source $cmd $source", $value);
        // line7
        $x71 = 0;
        $y71 = $y - $padding - $distance;
        $x72 = $padding;
        $y72 = $y - $padding - $distance;

        $cmd .=' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x71 . ',' . $y71 . ' ' . $x72 . ',' . $y72 . '" \ ';
        //passthru("convert $source $cmd $source", $value);
        // line 8
        $x81 = $padding + $distance;
        $y81 = $y - $padding;
        $x82 = $padding + $distance;
        $y82 = $y;

        $cmd .=' -stroke black -strokewidth ' . $wmark . ' -draw "line ' . $x81 . ',' . $y81 . ' ' . $x82 . ',' . $y82 . '" ';
        passthru("convert $source $cmd $source", $value);

        return $source;
    }

}

?>